package com.example.common.util;

import cn.hutool.core.codec.Base64;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import javax.imageio.ImageIO;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;

/**
 * @author zjarlin
 * @since 2023/2/25 10:18
 */
public class Qrutil {

    // 二维码尺寸
    private static final int QRCODE_SIZE = 335;

    // 用二维码生成新图片，新图片加高多少，比如加的字体大小为24，这里就设置成26
    private static final int FONT_SIZE_HEIGHT = 26;

    // 用二维码生成新图片，宽度
    private static final int BUFFEREDIMAGE_SIZE_WIDTH = QRCODE_SIZE;

    // 用二维码生成新图片，高度
    private static final int BUFFEREDIMAGE_SIZE_HEIGHT = QRCODE_SIZE + FONT_SIZE_HEIGHT;

    @Value("${file.genQrCodePath}")
    private String genRootPath;

    @NotNull
    public static String getLogoQrCodeBase64String(String logoStr, String qrCodeStr) {
        BufferedImage generate = QrCodeUtil.generate(qrCodeStr, QrConfig.create());
        BufferedImage bufferedImage = addNote(generate, logoStr, NotePosition.BOTTOM_CENTER);
        String s = imageToBase64(bufferedImage);
        return s;
    }

    public static BufferedImage addNote(BufferedImage image, String text, NotePosition position) {
        Graphics2D g2d = image.createGraphics();
        Font font = new Font("SansSerif", Font.PLAIN, 12);
        g2d.setFont(font);
        g2d.setColor(Color.BLACK);
        FontMetrics fm = g2d.getFontMetrics();
        int textWidth = fm.stringWidth(text);
        int x, y;
        switch (position) {
            case TOP_LEFT:
                x = 0;
                y = fm.getAscent();
                break;
            case TOP_CENTER:
                x = (image.getWidth() - textWidth) / 2;
                y = fm.getAscent();
                break;
            case TOP_RIGHT:
                x = image.getWidth() - textWidth;
                y = fm.getAscent();
                break;
            case MIDDLE_LEFT:
                x = 0;
                y = image.getHeight() / 2;
                break;
            case MIDDLE_CENTER:
                x = (image.getWidth() - textWidth) / 2;
                y = image.getHeight() / 2;
                break;
            case MIDDLE_RIGHT:
                x = image.getWidth() - textWidth;
                y = image.getHeight() / 2;
                break;
            case BOTTOM_LEFT:
                x = 0;
                y = image.getHeight() - fm.getDescent();
                break;
            case BOTTOM_CENTER:
                x = (image.getWidth() - textWidth) / 2;
                y = image.getHeight() - fm.getDescent();
                break;
            case BOTTOM_RIGHT:
                x = image.getWidth() - textWidth;
                y = image.getHeight() - fm.getDescent();
                break;
            default:
                throw new IllegalArgumentException("Invalid text position: " + position);
        }
        g2d.drawString(text, x, y);
        g2d.dispose();
        image.flush();
        return image;
    }

    @SneakyThrows
    public static String imageToBase64(BufferedImage bufferedImage) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
        ImageIO.write(bufferedImage, "png", baos);//写入流中
        byte[] bytes = baos.toByteArray();//转换成字节
        String png_base64 = Base64.encode(bytes);
        png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
        return "data:image/png;base64," + png_base64;

    }

    /**
     * 给二维码下方添加说明文字
     *
     * @param image 原二维码
     * @param note  说明文字
     * @return 带说明文字的二维码
     */
    public static BufferedImage addNote(BufferedImage image, String note) {
        Image src = image.getScaledInstance(QRCODE_SIZE, QRCODE_SIZE, Image.SCALE_DEFAULT);
        BufferedImage tag;
        if (note.length() <= 24) {
            //生成新图片的大小
            tag = new BufferedImage(BUFFEREDIMAGE_SIZE_WIDTH, BUFFEREDIMAGE_SIZE_HEIGHT, BufferedImage.TYPE_INT_RGB);
        } else {
            //这句代码还没调试过，这里表示文字需要折行
            tag = new BufferedImage(300, 345, BufferedImage.TYPE_INT_RGB);
        }
        //设置低栏白边
        Graphics g1 = tag.getGraphics();
        //设置文字
        Graphics2D g2 = tag.createGraphics();
        Font font = new Font("微软雅黑", Font.BOLD, 24);
        g2.setFont(font);
        g2.setColor(Color.BLACK);
        if (note.length() <= 24) {
            //下面这个26要和tag = new BufferedImage(330, 356,BufferedImage.TYPE_INT_RGB);356-330=26对上
            g1.fillRect(0, QRCODE_SIZE, QRCODE_SIZE, FONT_SIZE_HEIGHT);
            //文字在图片上的位置
            g2.drawString(note,/*QRCODE_SIZE/2-note.length()*8-14*/20, QRCODE_SIZE + font.getSize());
        } else {
            //这里的代码还没测试过
            g1.fillRect(0, QRCODE_SIZE, QRCODE_SIZE, 45);
            //下面两次表示文件需要换行显示
            g2.drawString(note.substring(0, 24), 5, QRCODE_SIZE + font.getSize());
            g2.drawString(note.substring(24), QRCODE_SIZE / 2 - (note.length() - 24) * 8 - 14, QRCODE_SIZE + font.getSize() * 2 + 4);
        }
        g1.drawImage(src, 0, 0, null);
        g1.dispose();
        g2.dispose();
        image = tag;
        image.flush();
        return image;
    }

    public enum NotePosition {
        TOP_LEFT,
        TOP_CENTER,
        TOP_RIGHT,
        MIDDLE_LEFT,
        MIDDLE_CENTER,
        MIDDLE_RIGHT,
        BOTTOM_LEFT,
        BOTTOM_CENTER,
        BOTTOM_RIGHT
    }
    //@Test
    //public void djaosjo() {

    //}

}
